//--------------------------------------------------------------------------------------
// StaticMesh.hlsl
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Globals
//--------------------------------------------------------------------------------------
cbuffer cbPerObject : register( b0 )
{
    matrix      g_mWorldViewProjection  : packoffset( c0 );
    matrix      g_mWorld                : packoffset( c4 );
};

//--------------------------------------------------------------------------------------
// Input / Output structures
//--------------------------------------------------------------------------------------
struct VS_INPUT
{
    float4 vPosition    : POSITION;
    float3 vNormal      : NORMAL;
    float2 vTexcoord    : TEXCOORD0;
};

struct VS_OUTPUT
{
    float3 vNormal      : NORMAL;
    float2 vTexcoord    : TEXCOORD0;
    float4 vPosition    : SV_POSITION;
};

//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
VS_OUTPUT VSMain( VS_INPUT Input )
{
    VS_OUTPUT Output;
    
    Output.vPosition = mul( Input.vPosition, g_mWorldViewProjection );
    Output.vNormal = mul( Input.vNormal, (float3x3)g_mWorld );
    Output.vTexcoord = Input.vTexcoord;
    
    return Output;
}


//--------------------------------------------------------------------------------------
// Globals
//--------------------------------------------------------------------------------------
cbuffer cbPerObject : register( b0 )
{
    float4      g_vObjectColor          : packoffset( c0 );
};

cbuffer cbPerFrame : register( b1 )
{
    float3      g_vLightDir             : packoffset( c0 );
    float       g_fAmbient              : packoffset( c0.w );
};

//--------------------------------------------------------------------------------------
// Textures and Samplers
//--------------------------------------------------------------------------------------
Texture2D   g_txDiffuse : register( t0 );
SamplerState g_samLinear : register( s0 );

//--------------------------------------------------------------------------------------
// Input / Output structures
//--------------------------------------------------------------------------------------
struct PS_INPUT
{
    float3 vNormal      : NORMAL;
    float2 vTexcoord    : TEXCOORD0;
};

//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PSMain( PS_INPUT Input ) : SV_TARGET
{
    
#ifdef COLOR_ONLY
    #ifdef LIGHTING
        float fLighting = saturate( dot( g_vLightDir, Input.vNormal ) );
        fLighting = max( fLighting, g_fAmbient );
        return g_vObjectColor * fLighting;
    #else
        return g_vObjectColor * g_fAmbient;      
    #endif

#else        
    float4 vDiffuse = g_txDiffuse.Sample( g_samLinear, Input.vTexcoord );
    #ifdef LIGHTING        
        float fLighting = saturate( dot( g_vLightDir, Input.vNormal ) );
        fLighting = max( fLighting, g_fAmbient );
        return g_vObjectColor * vDiffuse * fLighting;    
    #else
        return g_vObjectColor * vDiffuse * g_fAmbient;      
    #endif
#endif 
}
